import React, { useState, useCallback, memo } from 'react'

type ChildProps = {
  click: () => void
}

type Child2Props = {
  count: number
}

const Child1 = memo(({ click }: ChildProps) => {
  console.log('Child1 组件更新')
  return (
    <div style={{ backgroundColor: 'lightsalmon', padding: 5 }}>
      子组件1：<button onClick={click}>点击</button>
    </div>
  )
})

const Child2 = React.memo(
  ({ count }: Child2Props) => {
    console.log('Child2 组件更新')
    return (
      <div style={{ backgroundColor: 'lightgoldenrodyellow', padding: 5 }}>子组件2 -- {count}</div>
    )
  },
  (prevProps, nextProps) => {
    return prevProps === nextProps
  }
)

const App = () => {
  const [count, setCount] = useState(0)
  const [theme, setTheme] = useState('lightseagreen')

  // useCallback()
  // 场景：在使用 React.memo 时，为了让组件每次更新时都能获取到相同引用的函数，就要用到 useCallback Hook
  // 注意：需要配合 React.memo 高阶函数一起使用

  // 作用：记忆传入的回调函数，被记忆的回调函数会一直生效，直到依赖项发生改变

  // useCallback()
  // 第一个参数：必选，需要被记忆的回调函数
  // 第二个参数：必选，依赖项数组，用于指定回调函数中依赖用的数据，类似与 useEffect 的第二个参数
  // 注意：即使没有依赖，也得传入空数组([])，此时，useCallback 记住的回调函数就会一直生效
  // 返回值：需要被记忆的 回调函数
  // useCallback 记住的回调函数会一直生效，直到依赖项发生改变

  // const handleClick = useCallback(() => {
  //   console.log('不依赖任何数据')
  // }, [])

  const handleClick = useCallback(() => {
    console.log('依赖 count 数据')
    setCount(count + 10)
  }, [count])

  return (
    <div style={{ backgroundColor: theme, padding: 10 }}>
      <button
        onClick={() => setTheme(theme === 'lightseagreen' ? 'lightskyblue' : 'lightseagreen')}
      >
        切换主题
      </button>

      <h1>计数器：{count}</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>

      <hr />

      {/* 子组件 */}
      <Child1 click={handleClick} />

      <hr />

      <Child2 count={5} />
    </div>
  )
}

export default App
